<?php

namespace App\Jobs\Publish;

use App\Classes\Publish\Publication;
use App\Models\Entity\Asset\Video\Vasseti;
use App\Models\Entity\Asset\Video\VassetiVcattag;
use App\Models\Task\Task;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\DB;

class VassetiJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
    protected $ids;
    protected $option;
    public $tries   = 1;
    public $timeout = 30;
    public $taskid;
    // 上线,下线,发布的where条件
    protected $upWhere          = ['online_status' => 0, 'publish_down_status' => 1];
    protected $publishWhere     = ['online_status' => 1, 'publish_status'      => 0, 'async_result' => 1];
    protected $downWhere        = ['online_status' => 1];
    protected $publishDownWhere = ['online_status' => 0, 'publish_down_status' => 0];

    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct($option, $ids = '', $taskid = '')
    {
        $this->option = $option;
        $this->ids    = $ids;
        $this->taskid = $taskid;
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        switch ($this->option[0]) {
            // 分发任务,将一个大任务划分为多个小任务
            case 'dispatch':
                $this->mydispatch($this->option[1]);
                break;
            // 上线小任务
            case 'up':
                $user_id = Publication::getField(new Task(), $this->taskid, 'user_id');
                Publication::updateMany(new Vasseti(), $this->ids, [
                    'online_status'       => 1, 
                    'publish_down_status' => 0, 
                    'user_id'             => $user_id, 
                    'online_at'           => date('Y-m-d H:i:s')
                ]);
                Publication::updateOne(new Task(), $this->taskid, [
                    'done_num' => DB::raw('done_num +'.count($this->ids)),
                ]);
                break;
            // 发布小任务
            case 'publish':
                $publish_small_chunk_num = config('custom.base.job.vasseti.publish_small_chunk_num');
                foreach ($this->ids->chunk($publish_small_chunk_num) as $chunk_ids) {
                    try {
                        // 获取媒资数据
                        $vassetis  = Vasseti::with(['directors', 'actors', 'vposteris', 'vcattags', 'vifiles'])
                            ->whereIn('id', $chunk_ids)->get();
                        // 处理媒资分类中间表数据, 并插入接口库
                        VassetiVcattag::whereIn('vasseti_id', $chunk_ids)->chunk($publish_small_chunk_num, function($vassetiVcattags) {
                            $vassetiVcattagDatas = self::makeVassetiVcattags($vassetiVcattags);
                            DB::connection('interface')->table('vasseti_vcattags')->insert($vassetiVcattagDatas);
                        });
                    } catch(\Exception $e) {
                        dd($e->getMessage());
                    }
                    // 拼装媒资数据, 产品包-媒资中间表数据
                    $vasseti_datas = self::makeVassetis($vassetis);
                    DB::connection('interface')->beginTransaction();
                    try {
                        DB::connection('interface')->table('vassetis')->insert($vasseti_datas);
                        DB::connection('interface')->commit();
                        Publication::updateMany(new Vasseti(), $chunk_ids, ['publish_status' => 1]);
                        Publication::updateOne(new Task(), $this->taskid, [
                            'done_num' => DB::raw('done_num + '.count($chunk_ids))
                        ]);
                    } catch (\Exception $e) {
                        DB::connection('interface')->rollback(); //事务回滚
                        dd($e->getMessage());
                    }
                }
                break;
            // 下线小任务
            case 'down':
                $user_id = Publication::getField(new Task(), $this->taskid, 'user_id');
                Publication::updateMany(new Vasseti(), $this->ids, [
                    'online_status'  => 0, 
                    'publish_status' => 0, 
                    'user_id'        => $user_id, 
                    'offline_at'     => date('Y-m-d H:i:s')
                ]);
                Publication::updateOne(new Task(), $this->taskid, ['done_num' => DB::raw('done_num +' . count($this->ids))]);
                break;
            // 下线发布小任务
            case 'publishDown':
                $user_id = Publication::getField(new Task(), $this->taskid, 'user_id');
                Publication::deleteApi('vassetis', 'vasseti_id', $this->ids);
                Publication::deleteApi('vasseti_vcattags', 'vasseti_id', $this->ids);
                Publication::updateMany(new Vasseti(), $this->ids, [
                    'publish_down_status' => 1, 
                    'user_id'             => $user_id, 
                ]);
                Publication::updateOne(new Task(), $this->taskid, ['done_num' => DB::raw('done_num +' . count($this->ids))]);
                break;
        }
    }
    
    /**
    * 分发任务具体执行代码
    */
    public function mydispatch($option)
    {
        switch ($option) {
            case 'up':
                $chunk_num = config('custom.base.job.vasseti.online_chunk_num');
                $where = $this->upWhere;
                break;
            case 'publish':
                $chunk_num = config('custom.base.job.vasseti.publish_chunk_num');
                $where = $this->publishWhere;
                break;
            case 'down':
                $chunk_num = config('custom.base.job.vasseti.offline_chunk_num');
                $where = $this->downWhere;
                break;
            case 'publishDown':
                $chunk_num = config('custom.base.job.vasseti.publish_chunk_num');
                $where = $this->publishDownWhere;
                break;
        }
        Publication::chunk(new Vasseti(), $this, $where, $chunk_num, [$option]);
    }
      
    /**
    * 拼装数据
    */
    public static function makeVassetis($vassetis)
    {
        $datas = [];
        $data  = [];
        foreach ($vassetis as $vasseti) {
            // 服务商ID 目前服务商ID是瀚动的
            $data['sp_id']         = 1;
            $data['vasseti_id']    = $vasseti->id;
            $data['title']         = $vasseti->title;
            $data['subtitle']      = $vasseti->subtitle;
            $data['score']         = $vasseti->score;
            $data['long_desc']     = $vasseti->long_desc;
            $data['short_desc']    = $vasseti->short_desc;
            $data['episode']       = $vasseti->episode;
            $data['async_content'] = $vasseti->async_content;
            if ($vasseti->vcattags->first()) {
                $data['tags'] = $vasseti->vcattags->implode('id', '&');
            } else {
                $data['tags'] = '';
            }
            // 导演
            if ($vasseti->directors->first()) {
                $data['directors'] = $vasseti->directors->implode('name', '&');
            } else {
                $data['directors'] = '';
            }
            // 演员
            if ($vasseti->actors->first()) {
                $data['actors'] = $vasseti->actors->implode('name', '&');
            } else {
                $data['actors'] = '';
            }
            // 翻译, 目前是导演数据
            $data['translators'] = $data['directors'];
            // 根据图片的类型, 分为1:海报, 2:照片
            if ($vasseti->vposteris->first()) {
                $temp            = $vasseti->vposteris->groupBy('vimgtag_id');
                $data['posters'] = $temp->get(1) ? $temp->get(1)->toJson() : '';
                $data['imgs']    = $temp->get(2) ? $temp->get(2)->toJson() : '';
                unset($temp);
            } else {
                $data['imgs']    = '';
                $data['posters'] = '';
            }
            // 流
            $data['streams'] = '';
            // 视频文件,音频文件
            if ($vasseti->vifiles->first()) {
                $data['vifiles'] = json_encode($vasseti->vifiles);
            } else {
                $data['vifiles'] = '';
            }
            $datas[] = $data;
        }
        return $datas;
    }

    /**
    * 拼装媒资分类中间表数据
    */
    public static function makeVassetiVcattags($vassetiVcattags)
    {
        $datas = [];
        $data  = [];
        foreach ($vassetiVcattags as $vassetiVcattag) {
            $data['vasseti_id'] = $vassetiVcattag->vasseti_id;
            $data['vcattag_id'] = $vassetiVcattag->vcattag_id;
            $datas[]            = $data;
        }
        return $datas;
    }
}
